﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Utility.NodeGraphs;
using System.Linq;
using System;
using UnityEditor;

namespace Utility.BehaviourTree
{
	[NodeGraphEditor (typeof (BTSetting_NodeGraph))]
	public class BTSetting_NodeGraphEditor : TreeNodeGraphEditor
	{
		public override GenericMenu BuildContextMenu (NodeGraph graph)
		{
			GenericMenu menu = new GenericMenu ();
			//root
			AddMenuItem_AddRootNode (menu, graph, typeof (BTRootNode));
			//composite
			foreach (var type in BTSetting_NodeGraph.CompositeNodeTypes)
			{
				AddMenuItem_AddCompositeNode (menu, graph, type);
			}
			//decorator
			foreach (var type in BTSetting_NodeGraph.DecoratorNodeTypes)
			{
				AddMenuItem_AddDecoratorNode (menu, graph, type);
			}
			//leaf
			foreach (var type in BTSetting_NodeGraph.LeafNodeTypes)
			{
				AddMenuItem_AddLeafNode (menu, graph, type);
			}

			menu.AddSeparator ("");
			AddMenuItem_FormatNodeGraph (menu, graph);

			menu.AddSeparator ("");
			AddMenuItem_ClearAll (menu, graph, "Remove All");

			return menu;
		}

		//root
		void AddMenuItem_AddRootNode (GenericMenu menu, NodeGraph graph, Type nodeType)
		{
			string name = TrimSuffix (nodeType.Name, "Node");
			string text = name;
			if ((graph as TreeNodeGraph).RootNodeExist)
			{
				menu.AddDisabledItem (new GUIContent (text));
			}
			else
			{
				AddMenuItem_AddNode<BTSetting_Node> (menu, graph, InitRootNode, nodeType, text, name);
			}
		}
		//composite
		void AddMenuItem_AddCompositeNode (GenericMenu menu, NodeGraph graph, Type nodeType)
		{
			string name = TrimSuffix (nodeType.Name, "Node");
			string text = "Composite Node/" + name;
			AddMenuItem_AddNode<BTSetting_Node> (menu, graph, InitCompositeNode, nodeType, text, name);
		}
		//decorator
		void AddMenuItem_AddDecoratorNode (GenericMenu menu, NodeGraph graph, Type nodeType)
		{
			string name = TrimSuffix (nodeType.Name, "Node");
			string text = "Decorator Node/" + name;
			AddMenuItem_AddNode<BTSetting_Node> (menu, graph, InitDecoratorNode, nodeType, text, name);
		}
		//leaf
		void AddMenuItem_AddLeafNode (GenericMenu menu, NodeGraph graph, Type nodeType)
		{
			string name = TrimSuffix (nodeType.Name, "Node");
			string text = "Leaf Node/" + name;
			AddMenuItem_AddNode<BTSetting_Node> (menu, graph, InitLeafNode, nodeType, text, name);
		}

		#region utility
		void InitRootNode (BTSetting_Node node, object nodeType)
		{
			Type type = (Type)nodeType;

			node.nodeType = BTSetting_Node.NodeTypes.Decorator;
			node.typeName = type.FullName;

			node.AddNewPort (0, 1, Vector2.right * 50);
			node.nodeName = node.name;

			node.isRoot = true;
		}


		void InitCompositeNode (BTSetting_Node node, object nodeType)
		{
			Type type = (Type)nodeType;

			node.nodeType = BTSetting_Node.NodeTypes.Composite;
			node.typeName = type.FullName;

			node.AddNewPort (0, 1, Vector2.right * 50);
			node.nodeName = node.name;
		}

		void InitDecoratorNode (BTSetting_Node node, object nodeType)
		{
			Type type = (Type)nodeType;

			node.nodeType = BTSetting_Node.NodeTypes.Decorator;
			node.typeName = type.FullName;

			node.AddNewPort (0, 1, Vector2.right * 50);
			node.nodeName = node.name;
		}

		void InitLeafNode (BTSetting_Node node, object nodeType)
		{
			Type type = (Type)nodeType;

			node.nodeType = BTSetting_Node.NodeTypes.Leaf;
			node.typeName = type.FullName;

			node.nodeName = node.name;
		}


		string TrimSuffix (string str, string suffix)
		{
			return str.EndsWith (suffix) ? str.Substring (0, str.Length - suffix.Length) : str;
		}
		#endregion
	}
}